For a demo that uses a texteditor, see Eddie!
For an article on program design and a description of Eddie, see Program Design with Eddie
Sending commands to a texteditor.
In Liberty BASIC, commands are sent to controls as strings of text inside of quotation marks,. Texteditors can display text printed to them. For that reason, when we send a command to a texteditor, we must precede the command with the ! character. This tells Liberty BASIC to use the text inside of the quotation marks as a command, rather than as a string of text that should be displayed.
'this displays text on the texteditor: #1.te "Hello World!" 'this sends a command to a texteditor: #1.te "!CLS"
Clearing the texteditor.
Since Eddie is a source code editor, we need to provide a way for the user to begin a new source code file. This requires us to delete any existing text from the texteditor so the user can start fresh. To remove all text from a texteditor control, use the !CLS command:
'this clears all text from texteditor:
#1.te "!CLS"
Here is the routine to begin a new source code file in Eddie:
[new]
#1.te "!CLS"
Wait
Adding text to the texteditor.
Text is added to a texteditor by printing it to the control.
print #1.te, "Here is some text."
The PRINT command and the comma can be omitted. This code is interpreted by Liberty BASIC in exactly the same way as the previous code:
#1.te "Here is some text."
Each subsequent command to print text to the texteditor causes the new text to be added to the existing text in the texteditor.
#1.te "Here is some text."
#1.te "Here is some more text."
The code above looks like this in a texteditor:
Here is some text.
Here is more text.
Semicolons and Carriage Returns.
Each PRINT statement automatically causes a carriage return. In the code above, the two text strings are displayed on two separate lines. If we want to add text without causing it to appear on a new line, we need to end our command with a semicolon. This tells Liberty BASIC that it should not insert a carriage return.
#1.te "Here is some text. ";
#1.te "Here is more text on the same line."
The code above looks like this in a texteditor:
Here is some text. Here is more text on the same line.
Wrapping lines of text.
Many applications that offer the ability to create and edit text allow the user to type an entire paragraph without hitting the ENTER key, but with the text wrapping automatically when it reaches the visible right side of the editor window. A Liberty BASIC texteditor does not allow that kind of automatic wrapping. As the user types, the control scrolls to the right to accomodate the text, until a user hits ENTER. A very long line of text will wrap when it reaches the scrollbar limit. There is no way to cause a Liberty BASIC texteditor to force a line wrap at the visible right edge. It will always scroll as the user types.
If the code prints text to the texteditor, carriage returns are included automatically, unless they are suppressed, as described above.
If you have a need for a text control that allows the user to type with automatic line wrapping, you can use a textbox that has been modified with STYLEBITS. See Janet's helpful demonstration here: Stylebits Corner - Textboxes.
STYLEBITS and Texteditors
Most stylebits commands do not work with texteditor controls. Texteditor controls are not standard Windows EDIT controls, so they cannot be modified, either with STYLEBITS or by API calls.
Texteditors in Dialog Windows
For best results, do not use texteditors in dialog windows. Dialog windows trap the event of the user hitting the ENTER key. Try this code. Type something, the hit ENTER. The dialog has a .default button, which is activated when ENTER is pressed. The button is an EXIT button, so hitting ENTER causes the dialog window to close!
nomainwin texteditor #d.te, 10,10,200,200 button #d.default, "Exit",[quit],UL,220,10 open "Dialog with Texteditor" for dialog as #d #d "trapclose [quit]" #d.te "!setfocus" wait [quit] close #d:end
Placing the contents of a file into a texteditor.
Liberty BASIC gives us an easy way to place the contents of a file into a texteditor. The new text will replace any existing contents of the texteditor. To do this, open the file for INPUT, then use the !contents #file command, then close the file. It only requires three simple lines of code:
open "filename.txt" for input as #f
#1.te "!contents #f"
close #f
This method is perfect for opening a new file in Eddie. We allow the user to select a file with a FILEDIALOG. A filedialog has three parameters. The first is the caption that appears on the filedialog. The caption will say something like "Open Bitmap", "Open File", "Save File" and so on. The second part is the template string that specifies which file extensions should be displayed in the listbox of files. To open basic source code files, the template string is "*.bas". The asterisk ( * ) is a wildcard character. It stands in for any number of characters. Using the "*.bas" template causes all files with the extension BAS to be displayed. To cause all files of every type to be displayed, use this template: "*.*". To cause multiple file types to be displayed, separate the types with a semicolon. This template causes both BAS and TXT files to be displayed: "*.bas;*.txt". The third parameter is the receiver variable. After the user dismisses the filedialog, this variable contains the filename he has chosen, or an empty string if he has cancelled the filedialog without making a choice.
filedialog "Caption","*.ext",receiverVar$
In Eddie, the dialog to OPEN a file looks like this:
filedialog "Open","*.bas",openfile$
We check to make sure he has not cancelled the filedialog without selecting a file. If the dialog was cancelled, the receiver variable contains an empty string. If this is the case, the program simply stops and waits for more user events. If the user has selected a file, Eddie uses the method described above to clear the texteditor and replace any exising text with the contents of the file:
[open]
filedialog "Open","*.bas",openfile$
if openfile$="" then wait
open openfile$ for input as #f
'dump contents of file into texteditor
#1.te "!contents #f"
close #f
Wait
Retrieving text from a texteditor. - Printing hard copies and saving files to disk.
It only takes one line of code to retrieve the entire contents of the texteditor into a single string.
#1.te "!contents? text$"
After this command, the contents of Eddie are contained in the string variable called text$. Once we have the contents in a string variable, we can print a hard copy of it with LPRINT and DUMP. LPRINT causes the string to be sent to the printer to make a hard copy. DUMP causes the printing to begin immediately.
[print]
'get contents of texteditor into string variable
#1.te "!contents? text$"
if text$="" then
notice "No text to print."
wait
end if
'send text to printer
lprint text$
'cause printing to happen now
dump
Wait
Eddie can also use the variable containing the contents of the texteditor to write the file to disk. We first need to ask the user for a filename, using the FILEDIALOG command again. If the word SAVE appears in the caption we give to the filedialog, Liberty BASIC creates a save-type dialog. If the user cancels the filedialog without setting a filename, we simply stop and wait for more user events.
'if the word SAVE is in the caption, LB
'automatically creates a SAVE dialog
filedialog "Save As","*.bas",savefile$
if savefile$="" then wait
Eddie will also check to make sure that the user has specified the proper extension for BASIC source code file, which is BAS. If a file is saved with a name that has no extension, it will only be displayed in filedialogs that have the template "*.*". To make sure the user has entered the proper extension, Eddie will look at the last four characters of the filename. They should be "*.bas". Eddie checks these using the RIGHT$() function. This function reads the characters from the right side of a string, and it reads as many characters as the function specifies:
txt$ = right$("FIDO IS A DOG.", 4)
After the command above, the variable "txt$" contains "DOG." Because Liberty BASIC string variables are case sensitive, variables containing "dog" and "DOG" are different. To do a string comparison, we must make sure the strings are in the same case. We can do with in Eddie with the LOWER$() function. It returns the string in all lowercase letters.
'make sure that user had given the file a *bas extension
if right$(lower$(savefile$),4)<>".bas" then
savefile$=savefile$+".bas"
end if
If we find that the last four characters are not ".bas", then we add the extension to the filename for the user.
Now we can get the contents of the texteditor into a string variable:
'get contents of texteditor into string variable
#1.te "!contents? text$"
if text$="" then
notice "No file to save."
wait
end if
We can now open a file for OUTPUT. This is the mode used to write to a file. All previous file contents are removed, and the file now contains the new contents. In this case, the new contents of the file are the contents of the texteditor.
'open file and write text to it
open savefile$ for output as #f
#f text$
close #f
Wait
Here is the entire routine Eddie uses to save a file to disk:
[save]
'if the word SAVE is in the caption, LB
'automatically creates a SAVE dialog
filedialog "Save As","*.bas",savefile$
if savefile$="" then wait
'make sure that user had given the file a *bas extension
if right$(lower$(savefile$),4)<>".bas" then
savefile$=savefile$+".bas"
end if
'get contents of texteditor into string variable
#1.te "!contents? text$"
if text$="" then
notice "No file to save."
wait
end if
'open file and write text to it
open savefile$ for output as #f
#f text$
close #f
Wait
What's in the EDIT menu.
Liberty BASIC texteditors have an automatic EDIT menu that is inserted on the menubar, and it also pops up automatically when the user clicks the right mouse button inside the texteditor. All of these functions are available and do not need to be coded in the program. There are also hot keys to call them:
Locating the EDIT Menu
Liberty BASIC places the EDIT menu on the right side of the menubar. We can locate it where we want. Since the EDIT menu typically follows the FILE menu in Windows applications, we'll put it there. To locate the EDIT menu on the menubar, just include it in the list of menus. Use [b] only [/b] the name of the menu, "Edit." Do not include any menu items or branch labels. Do not use an ampersand ( & ) in the EDIT menu caption, like this, "&Edit."
Menu #1, "&File", "&New", [new], "&Open", [open], "&Save", [save],_
|,"&Print", [print], "E&xit", [quit]
Menu #1, "Edit"
Menu #1, "&Run","R&un", [run]
Menu #1, "&Help", "He&lp", [help], "&About", [about]
EDIT functions.
We can write code for EDIT functions if we'd like. Eddie has buttons for Cut, Copy and Paste, so we'll have to add code to accomplish these things. They are very simple commands:
#1.te "!cut"
#1.te "!copy"
#1.te "!paste"
As they appear in Eddie:
[cut]
#1.te "!cut"
wait
[copy]
#1.te "!copy"
wait
[paste]
#1.te "!paste"
wait
Resizing the texteditor.
Liberty BASIC makes it easy to cause the texteditor to resize automatically when the user resizes the window. The texteditor will grow or shrink so that it is the same distance from the window's borders as it was when the window was first opened. To cause this to happen we use this command:
#1.te "!autoresize"
Fonts in the texteditor.
We can set the font that is used to display text in a texteditor, but we can only have one font for all of the text. One word in the middle of a sentence cannot be bold, for instance. The font command looks like this:
#1.te "!font facename [width] height [attributes]"
The facename must be read by Liberty BASIC as a single word. Fonts whose facenames are multiple words, like Times New Roman, must replace the spaces with underscores, like this: Times_New_Roman.
The font size can be set in pixels, or it can be set in points. To set the font size in pixels, you need to designate both the width and the height. If the width is set to be "0", the default width for the chosen font will be used. If the width is given a value, that width will be used. This command sets the font to be Times New Roman with a width of 8 pixels per character and a height of 16 pixels per character:
#1.te "!font Times_New_Roman 8 16"
This command uses the font's default width for the height:
#1.te "!font Times_New_Roman 0 16"
To set a font size using points, omit the width parameter. In the generic font command above, you can see that [width] is in square brackets. That is a standard way of noting optional parameters when describing syntax. It is not actually used in code. Here is a command that sets the font to Times New Roman, size 12 points:
#1.te "!font Times_New_Roman 12"
The attributes are optional. They can be one of more of these: italic, bold, strikeout, underscore. This command sets the font to be Times_New_Roman, with attributes for bold and italic:
#1.te "!font Times_New_Roman 12 bold italic"
In Liberty BASIC, a window can be given a "font" command. This causes the window and all of its controls to use the designated font. Individual controls can also receive font commands, which override the font command to the window. Eddie sets the window font to MS Sans Serif, 10 points. The texteditor uses Courier New, 10 points:
'set the font for the window and controls
#1 "font ms_sans_serif 10"
'set a custom font for the texteditor
#1.te "!font courier_new 10"
Eddie uses Courier New to display the text, because source code looks best in a mono-spaced font. This is a font where each letter takes up the same width as each other letter. In a variable-width font, letters do not take the same width. A "l" takes a smaller space than a "M" for instance. Code is easiest to view and understand if everything lines up, so Eddie uses the mono-spaced font.